package demo.db.redis.jedis.monitor;

import java.util.List;

import org.junit.Test;

import com.alibaba.fastjson.JSONObject;

import demo.db.redis.jedis.JedisDemo;
import redis.clients.jedis.Jedis;
import redis.clients.util.Slowlog;

/**
 * 
 * <h1>Redis 慢日志概览</h1> Redis Slow Log是一个系统，用于记录超过指定执行时间的查询。
 * 执行时间不包括IO操作，如与客户端交谈，发送回复等等，但只是实际执行命令所需的时间（这是执行命令的唯一阶段，其中线程被阻止并且不能同时服务于其他请求）。
 * 
 * 您可以使用两个参数配置慢日志： slowlog-log-slow-than 告诉 Redis
 * 为了记录命令，执行时间（微秒）超过了多少。默认是10000微秒，即10ms。请注意，负数将禁用慢日志，而值为零将强制记录每条命令。
 * slowlog-max-len
 * 是慢日志的长度。最小值为零。当记录新的命令并且慢日志已经处于其最大长度时，为了留出空间，将最老的命令从记录的命令队列中移除。
 * 配置可以通过编辑redis.conf 或服务器运行时使用 CONFIG GET 和 CONFIG SET 命令来完成。
 * 
 * 以Rdis的性能来说，正常的执行时间一般在10微秒级别（单实例OPS可以达到10W）。
 * 所以，设置slowlog-log-slower-than为1000，即1毫秒已经绰绰有余。
 * 
 * <h1>查看慢日志</h1>
 * 慢日志在内存中累积，因此没有写入关于慢命令执行信息的文件。这使得日志记录非常快，可以启用所有命令的日志记录（将slowlog-log-slow-
 * config配置参数设置为零），同时影响较小。
 * 
 * 要读取慢日志，使用SLOWLOG GET命令，该命令将返回慢日志中的每个条目。可以仅返回N个最近的条目，并将其他参数传递给该命令（例如SLOWLOG
 * GET 10）。
 * <h1>清理慢日志</h1> 另外，可以通过命令slowlog reset清理掉所有保存的慢日志。
 * 说明：Redis4.0或者更高的版本多了两个额外的字段：客户端IP端口以及客户端名称。客户端名称可以通过命令：client setname
 * 进行自定义设置。
 */
public class RedisSlowLog {

    /**
     * 每个条目由四个字段组成：
     * <li>每个慢日志条​​目的唯一渐进标识符。
     * <li>处理记录的命令的UNIX时间戳。
     * <li>执行所需的时间量，以微秒为单位。
     * <li>组成命令参数的数组。
     * <p>
     * 该条目的唯一ID可用于避免多次处理缓慢的日志条目（例如，您可能有一个脚本为每个新的慢日志条目发送电子邮件警报）。 在 Redis
     * 服务器执行过程中，ID永远不会被重置，只有服务器重启才会重置它。
     */
    @Test
    public void slowLog() {
        try (Jedis jedis = JedisDemo.newJedis()) {
            System.out.println("----------------------------命令：slowlog get");
            List<Slowlog> list = jedis.slowlogGet();
            list.forEach(e -> System.out.println(JSONObject.toJSONString(e)));
            System.out.println("----------------------------命令：slowlog get 11");
            List<Slowlog> list2 = jedis.slowlogGet(11);
            list2.forEach(e -> System.err.println(e));
        }
    }

    /**
     * 获取慢日志的当前数量# 使用命令 SLOWLOG LEN 可以获得慢日志的长度 。
     */
    @Test
    public void slowLogLen() {
        try (Jedis jedis = JedisDemo.newJedis()) {
            System.out.println("----------------------------命令：slowlog len");
            long length = jedis.slowlogLen();
            System.out.println("slowlog len = " + length);
        }
    }

    /**
     * 重置慢日志# 你可以使用 SLOWLOG RESET 命令重置慢日志。一旦删除，信息将永远丢失。
     */
    @Test
    public void slowLogReset() {
        try (Jedis jedis = JedisDemo.newJedis()) {
            System.out.println("----------------------------命令：SLOWLOG RESET");
            // OK
            String str = jedis.slowlogReset();
            System.out.println("slowlog reset = " + str);
        }
    }

}
